'use strict';

const {
	XMLParser
} = require("fast-xml-parser");
const db = uniCloud.database();
const {
	mainSpaceId
} = require('config-main-space')
const wmzSoundSdk = uniCloud.importObject('wmz-sound-sdk')
exports.main = async (event, context) => {
	let response = {
		mpserverscssComposedResponse: true,
		statusCode: 200
	};

	let data = event.body;
	if (event.isBase64Encoded) {
		data = new Buffer(data, 'base64').toString();
	}

	let res = {};
	let payObj = {};

	const path = event.path;

	switch (path) {
		case '/alipay':

			payObj.name = '支付宝支付';
			payObj.way = 'alipay';

			let queryArr = data.split("&");
			queryArr.forEach(function(item) {
				let key = item.split("=")[0];
				res[key] = item.split("=")[1];
			});
			res.total_fee = res.total_amount * 100;
			res.transaction_id = res.trade_no;

			if (res.voucher_detail_list) {
				let voucherStr = res.voucher_detail_list;
				let vouchers = JSON.parse(decodeURIComponent(voucherStr));
				if (vouchers && vouchers.length > 0) {
					let voucherArray = [];
					vouchers.forEach(function(voucher) {
						let caliVoucherAmount = voucher.amount ? Math.round((parseFloat(voucher
							.amount) * 100)) : 0;

						voucherArray.push({
							voucher_id: voucher.voucherId ? voucher.voucherId : null,
							voucher_type: voucher.type ? voucher.type : null,
							voucher_name: voucher.name ? voucher.name : null,
							voucher_money: caliVoucherAmount
						});
					});

					if (voucherArray && voucherArray.length > 0) {
						res.alipay_vouchers = voucherArray;
					}
				}
			}

			break;
		case '/wechat':

			payObj.name = '微信支付';
			payObj.way = 'wechat';

			const parser = new XMLParser();
			res = parser.parse(data);
			res = res.xml;

			try {
				//特殊处理transaction_id
				let transaction_ids = data.split('<transaction_id><![CDATA[');
				if (transaction_ids.length > 0) {
					res.transaction_id = transaction_ids[1].split("]]></transaction_id>")[0];
				}
			} catch (e) {
				uniCloud.logger.info("微信支付支付通知异常: ", JSON.stringify(e));
			}

			break;
		default:

			uniCloud.logger.info(`支付通知标识不正确`);
			return response;
	}

	if (res && ((res.return_code && 'SUCCESS' === res.return_code) || (res.trade_status && 'TRADE_SUCCESS' ===
			res.trade_status))) {
		let outTradeNo = res.out_trade_no ? res.out_trade_no : null;
		let transactionId = res.transaction_id ? res.transaction_id : null;
		let alipayVouchers = res.alipay_vouchers ? res.alipay_vouchers : null;

		if (!outTradeNo) {
			uniCloud.logger.info(`outTradeNo参数丢失`);
			return response;
		}
		if (!transactionId) {
			uniCloud.logger.info(`transactionId参数丢失`);
			return response;
		}

		let queryOrder = {
			order_no: outTradeNo,
			is_delete: 0
		};

		let orderRes = await db.collection('wmzmall-collection-order').where(queryOrder).orderBy("create_time",
			"desc").limit(1).get();
		if (!orderRes || !orderRes.data || orderRes.data.length < 1) {
			uniCloud.logger.info(`[${outTradeNo}]对应的订单数据不存在`);
			return response;
		}

		let queryPay = {
			order_no: outTradeNo,
			is_delete: 0
		};

		let payRes = await db.collection('wmzmall-collection-pay').where(queryPay).orderBy("create_time",
				"desc")
			.limit(1).get();
		if (!payRes || !payRes.data || payRes.data.length < 1) {
			uniCloud.logger.info(`[${outTradeNo}]对应的支付数据不存在`);
			return response;
		}

		const [orderInfo] = orderRes.data;
		if (orderInfo.state === '已完成') {
			response.body = 'success';
			return response;
		}
		const [payInfo] = payRes.data;
		const datetime = new Date().getTime();

		const transaction = await db.startTransaction();

		try {

			let orderObj = {
				order_pay_no: transactionId,
				order_pay_state: '已付款',
				order_pay_time: datetime,
				state: '已完成'
			}

			if (alipayVouchers) {
				orderObj.alipay_vouchers = alipayVouchers;
			}

			let updateOrderResult = await transaction.collection('wmzmall-collection-order').doc(orderInfo._id)
				.update(orderObj);
			if (!updateOrderResult) {
				uniCloud.logger.info(`更新订单数据失败`);
				return response;
			}

			let collectionId = orderInfo.collectionId
			let balance_money = orderInfo.balance_money
			let collectionData = await db.collection('wmzmall-collection').doc(collectionId).get();
			collectionData = collectionData.data[0]
			await transaction.collection('wmzmall-collection').doc(collectionId).update({
				total: collectionData.total * 1 + orderInfo.order_total_money * 1,
				count: collectionData.count * 1 + 1
			})
			let collectionShareId = orderInfo.collectionShareId
			await transaction.collection('wmzmall-collection-share').doc(collectionShareId)
				.update({
					ispay: true
				});

			let payObj = {
				pay_time: datetime,
				pay_notify: JSON.stringify(data),
				pay_state: '已付款'
			}

			let updatePayResult = await transaction.collection('wmzmall-collection-pay').doc(payInfo._id)
				.update(
					payObj);
			if (!updatePayResult) {
				uniCloud.logger.info(`更新支付数据失败`);
				return response;
			}

			let title = '收款';
			let cate = '远程收单订单';
			let type = 0;
			let appId = orderInfo.app_id;
			let auto_deliver
			let appletInfoData = await db.collection('wmz-applet-info').doc(appId).get()
			appletInfoData = appletInfoData.data[0]
			if (appletInfoData && appletInfoData.auto_deliver) {
				auto_deliver = appletInfoData.auto_deliver
			}
			let shopId = orderInfo.shop_id;
			let orderNo = transactionId;
			let way = orderInfo.order_pay_way;
			let payMoney = orderInfo.order_total_money;
			let yj_money = collectionData.yj_money
			if (way.indexOf('支付宝') > -1) {
				way = '支付宝支付';
			}
			let shopie = {
				app_id: appId,
				shop_id: shopId,
				order_no: orderNo,
				title: title,
				cate: cate,
				type: type,
				way: way,
				money: payMoney,
				yj_money: yj_money,
				creator_id: orderInfo.create_uid,
				creator_name: orderInfo.creator_name,
				create_time: new Date().getTime(),
				openid: orderInfo.pay_openid,
				auto_deliver: auto_deliver,
				share_user_id: orderInfo.share_user_id
			};
			let addShopieResult = await db.collection('wmzmall-shopie').add(shopie);
			let tdb = uniCloud.database({
				provider: 'tencent',
				spaceId: mainSpaceId
			})
			await tdb.collection('wmzmall-shopie').add(shopie)
			if ('alipay' === payObj.way) {
				response.body = 'success';
			} else if ('wechat' === payObj.way) {
				response.body =
					`<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`;
			}

			await transaction.commit();

			if (payMoney === yj_money) {
				if (balance_money) {
					shopie.way = '余额'
					shopie.money = balance_money * 1
					await db.collection('wmzmall-shopie').add(shopie);
					await tdb.collection('wmzmall-shopie').add(shopie)
					let memberRes = await db.collection('wmzmall-member').doc(orderInfo.create_uid).get();
					memberRes = memberRes.data[0]
					await db.collection('wmzmall-member').doc(orderInfo.create_uid).update({
						member_amount: memberRes.member_amount - balance_money
					});
					const logRes = await db.collection('wmzmall-member-money-log').add({
						user_uid: orderInfo.create_uid,
						order_id: orderInfo._id,
						money: balance_money,
						money_fmt: '-' + balance_money / 100,
						source: '订单支付',
						type: '支出',
						remark: `订单支付-${balance_money / 100}`,
						time: new Date().getTime(),
						is_delete: 0,
						create_uid: orderInfo.create_uid,
						create_time: new Date().getTime()
					});
				}
			}

			let soundData = await db.collection('wmzmall-sound').where({
				shop_id: shopId
			}).get()
			soundData = soundData.data
			let content = '微信到账'
			payMoney = payMoney / 100
			if (way === '支付宝支付') {
				content = '支付宝到账'
			}
			if (soundData && soundData.length > 0) {
				for (var i in soundData) {
					await wmzSoundSdk.play({
						device_code: soundData[i].device_code,
						content: content + payMoney + "元"
					})
					await tdb.collection('wmz-sound-play').add({
						device_code: soundData[i].device_code,
						content: content + payMoney + "元",
						create_time: new Date().getTime(),
						app_id: appId,
						shop_id: shopId,
						order_no: orderNo
					})
				}
			}

		} catch (e) {
			await transaction.rollback();
			console.error(`transaction error`, e);
		} finally {
			return response;
		}
	}
}